package com.foreveross.proxyip.remote;

import java.io.Serializable;

import org.springframework.stereotype.Component;

import com.foreveross.proxyip.ProxyIpModel;
import com.foreveross.proxyip.ProxyipProvideException;
import com.foreveross.proxyip.application.offer.bean.ProxyIpDTO;
import com.foreveross.proxyip.local.ProxyIpPoolsManager;
import com.foreveross.proxyip.local.ProxyIpRmiChannelPool;
import com.foreveross.proxyip.local.ProxyIpSimplePool;
/**
 * 综合的代理Ip提供者策略
 * <p>综合远程统一代理与本地代理Ip下载两种策略一起使用，从统一代理IP下载后使用，成功的Ip继续放置在本地池中供下一次使用。
 * 一个ip在下载到本地池中后，可以供所有的渠道使用，当某个渠道不可使用后则进行记录，只有当所有渠渠道都不可用了该IP才丢弃。
 * <p>该策略能在一定程度上缓解代理IP服务的压力，同时能将单个代理IP极限使用，但同时带来的负作用是执行效率会有所降低
 * @author xiangsf 2014-09-22
 *
 */
@Component("proxyipComprehensiveProvider")
public class ProxyipComprehensiveProvider extends RmiProxyIpProvider {

	@Override
	public synchronized ProxyIpModel provideProxyIp() {
		//1、先从本地拿
		ProxyIpRmiChannelPool pool = ProxyIpPoolsManager.getInstanceManager().getRmiChannelPool();
		ProxyIpModel model = pool.getProxyIp();
		logger.info(String.format("获取到的代理ip:%s", model.getProxyIp()));
		return model;
	}

	@Override
	public synchronized ProxyIpModel provideProxyIp(Serializable channelId) {
		//1、先从本地拿
		ProxyIpRmiChannelPool pool = ProxyIpPoolsManager.getInstanceManager().getRmiChannelPool();
		ProxyIpModel model = pool.getProxyIp(channelId.toString());
		logger.info(String.format("获取到的代理ip:%s", model.getProxyIp()));
		return model;
	}

	@Override
	public synchronized void rollBackProxyIp(ProxyIpModel model) {
		if(model == null) return; 
		
		logger.info(String.format("回收代理ip状态:%s=%s", model.getProxyIp(), model.getUseStatus()));
		if(model.getUseStatus() == ProxyIpModel.UNENBLE){
			if(model.getHasRecycle()) return;//已经回收过了
			model.setHasRecycle(true);
			//增加本地池中IP对象的不可用
			if(model.getUserId() != null){
				ProxyIpRmiChannelPool pool = ProxyIpPoolsManager.getInstanceManager().getRmiChannelPool();
				model.addEnableStatus(model.getUserId().toString());
				if(pool.remove(model)){ //全部都不可用了，则反馈给统一代理服务
					try {
						ProxyIpDTO dto = new ProxyIpDTO(model.getIp(), model.getPort(), 
								model.getUserId() != null ? model.getUserId().toString() : null);
						dto.setState(ProxyIpModel.ALL_UNENBLE);
						proxyIPRMIService.recycle(dto, getProxyipServiceAuth());
					} catch (Exception e) {
						e.printStackTrace();
						throw new ProxyipProvideException(e);
					}
				}
			}
		}else if(model.getUseStatus() == ProxyIpModel.REPEAT_ENBLE){//完成任务后的回收代理Ip
			//将代理IP重新回到空闲中，供后面的任务使用
			ProxyIpRmiChannelPool pool = ProxyIpPoolsManager.getInstanceManager().getRmiChannelPool();
			model.setUseStatus(ProxyIpModel.ENBLE);
			pool.swapProxyIp(model);
		}
	}

}
